package com.magiccompass.alipay.barcode.controller;

import java.net.URI;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.magiccompass.alipay.barcode.constants.AlipayPartnerConstants;
import com.magiccompass.alipay.barcode.entity.AlipayBarcodeCancelRequest;
import com.magiccompass.alipay.barcode.entity.MerchantTransaction;
import com.magiccompass.alipay.barcode.model.AlipayBarcodeAllResponseAJAXModel;
import com.magiccompass.alipay.barcode.responsehandler.CancelResponseHandler;
import com.magiccompass.alipay.barcode.security.model.LoginUserModel;
import com.magiccompass.alipay.barcode.service.AlipayBarcodeService;
import com.magiccompass.alipay.barcode.service.MerchantBusinessService;
import com.magiccompass.alipay.barcode.util.AlipayBarcodeRequestUtil;
import com.magiccompass.alipay.barcode.util.UrlUtil;
import com.magiccompass.alipay.barcode.util.UserUtil;

@Controller
@RequestMapping(value="/alipayBarcodeCancelController")
public class AlipayBarcodeCancelController {
	static Logger logger = LogManager.getLogger(AlipayBarcodeCancelController.class.getName());
	@Resource(name="alipayBarcodeService")
	private AlipayBarcodeService alipayBarcodeService;
	@Resource(name="merchantBusinessService")
	private MerchantBusinessService merchantBusinessService;
	
	@RequestMapping(value="/cancelTest", method = {RequestMethod.GET,RequestMethod.POST})
    public String barcodeCancelTest(Model model,HttpServletRequest request) {
		return "alipay_barcode_gateway/cancelTest";
    }
	
	@RequestMapping(value="/cancel", method = {RequestMethod.GET,RequestMethod.POST})
    public String alipayBarcodeCancel(Model model,RedirectAttributes redirectAttributes,HttpServletRequest request) {
		String mtIdStr = request.getParameter("mtId");
		Integer mtId = new Integer(mtIdStr);
		
		MerchantTransaction mt =  merchantBusinessService.findMerchantTransactionById(mtId);

		AlipayBarcodeAllResponseAJAXModel returnJSON = new AlipayBarcodeAllResponseAJAXModel();
		returnJSON.setSuccess("true");
		returnJSON.setRedirect("true");
		returnJSON.setRedirectURL(request.getContextPath()+"/alipayBarcodeCancelController/result");

		LoginUserModel currentUser = UserUtil.getCurrentLoginUser();
		if(mt.getMerchant().getId().equals(currentUser.getDbUserInfo().getMerchant().getId())){ // merchant permit cancel it's own transaction
			if(AlipayBarcodeRequestUtil.isPaymentCanBeCanceled(mt)){
				AlipayBarcodeCancelRequest abcreq = AlipayBarcodeRequestUtil.alipayBarcodeCancelRequestEntityInit(mt,currentUser.getLoginUserId());

				TreeMap<String,String> barcodeRequestParameter4AlipayTreeMap = AlipayBarcodeRequestUtil.makeParameterMap4Alipay(abcreq, alipayBarcodeService);
				String sign = AlipayBarcodeRequestUtil.getSign(barcodeRequestParameter4AlipayTreeMap);
				abcreq.setSign(sign);
				
				alipayBarcodeService.save(abcreq);			

				barcodeRequestParameter4AlipayTreeMap.put("sign", sign);
				barcodeRequestParameter4AlipayTreeMap.put("sign_type", AlipayPartnerConstants.SIGN_TYPE);					
				
				if(abcreq.getId() != null){ // success insert into DB
					try {							
						RestTemplate restTemplate = new RestTemplate();
						String alipayBarcodeServerURL = AlipayPartnerConstants.ALIPAY_GATEWAY;
				    	String alipayBarcodeParameter = UrlUtil.makeParameterMap2String(barcodeRequestParameter4AlipayTreeMap);
				    	String restURL = alipayBarcodeServerURL+"?"+alipayBarcodeParameter;
				    	logger.info("restURL:"+restURL);
				    	URI uri = new URI(restURL);
				    	//String response = restTemplate.getForObject(restURL, String.class);
				    	String response = restTemplate.getForObject(uri, String.class);
				    	//String response = CancelResponseHandler.RESULT_SUCCESS_4_TEST;
				    	logger.info("response is:"+response);
						
						AlipayBarcodeAllResponseAJAXModel alipayResponse = CancelResponseHandler.handleResponse(response, abcreq, alipayBarcodeService);
						returnJSON.setResponseResultCode(alipayResponse.getResponseResultCode());
						returnJSON.setResponseResultReason(alipayResponse.getResponseResultReason());
					} catch (Exception e) {
						e.printStackTrace();
						returnJSON.setResponseResultCode("UNEXPECTED EXCEPTION");
						returnJSON.setResponseResultReason("Unexpected exception happened. Please contact support.");
					}
		    	}else{
		    		returnJSON.setResponseResultCode("UNEXPECTED");
					returnJSON.setResponseResultReason("Unexpected ERROR happened. Please contact support.");
		    	}
			}else{
				returnJSON.setResponseResultCode("ERROR");
				returnJSON.setResponseResultReason("This transaction can't cancel, please try refund. Otherwise, Please contact support.");
			}			
		}else{
			returnJSON.setResponseResultCode("ERROR");
			returnJSON.setResponseResultReason("Sorry, You don't have priviledge to canel this transaction.");
		}
		String returnStr = returnJSON.makeJSONString();
		logger.info(returnStr);
		redirectAttributes.addAttribute("resultCode", returnJSON.getResponseResultCode());
		redirectAttributes.addAttribute("resultReason", returnJSON.getResponseResultReason());
		return "redirect:/alipayBarcodeCancelController/result";
    }
	
	@RequestMapping(value="/result", method = {RequestMethod.GET,RequestMethod.POST})
    public String result(Model model,HttpServletRequest request) {
		String resultCode = request.getParameter("resultCode");
		String resultReason = request.getParameter("resultReason");
		
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
}
